ofsp2026 17_field
Created time
Mar 28, 2026 08:29 AM
type
Post
status
Published
date
Mar 28, 2026
slug
ofsp2026 17_field
summary
tags
ofsp2026
OpenFOAM
category
post
icon
password
Place
Last edited time
Mar 28, 2026 09:15 AM
Important
访问 https://aerosand.cc 以获取最近更新。
0. 前言
回忆前文,我们已经讨论了输入输出、命令行参数、时间和网格。OpenFOAM 的计算绝大多数是基于物理场的,本项目开始讨论 OpenFOAM 中的“场”。
本文主要讨论
理解场的代码结构
理解场的计算参与
编译运行 field 项目
1. 项目准备
终端输入命令,建立项目
测试初始求解器,提供脚本和说明。
2. 场的创建
2.1. dimensionSet
前文用到了 OpenFOAM 的单位预设,其定义在
$FOAM_SRC/OpenFOAM/dimensionSet/dimensionSets.C ,文件中还定义了很多预设单位再次摘阅如下
同样暂不深究代码实现细节。
我们可以设置自定义变量的物理单位,如
2.2. dimensionedType
查找类的定义
终端输入命令,查找源代码
找到并摘取其中的构造函数如下
相应的,在 OpenFOAM 代码中可以看到如下类似的构造
在 dimensionedType.H 中也定义了配套的成员函数,比如
相应的,我们可以便捷的使用 value() 成员函数,例如对上面的 airPressure 取值,再计算最大值。
当然 OpenFOAM 中还提供了其他的构造函数和成员函数,我们可以在不同情况下构造自己的有单位物理量。目前阶段来说,我们不需要继续深挖源代码。点到为止,明白确实可以这样用,并且以后按照这种方式去用就可以了。
注意,OpenFOAM 会检查数学计算式等号两遍的最终单位是否相同,如果不同则会强制报错并中断程序,后续代码会面临并解决这个问题。
2.3. volFields
我们会注意到 OpenFOAM 中有典型的语句如下
那么 volScalarField 是什么呢?又是如何构造场的呢?
API 页面
终端输入命令,查阅源文件
Tip
也许有同学还有疑惑“我怎么知道要查看这个文件”。参考 06_tensor 的讨论,安装 OFextension 插件后,直接在 volScalarField 关键字上右键跳转即可。也可以在 API 页面搜索关键词,以阅读相关页面。
代码 volFieldsFwd.H 中有类型定义如下
可以看到,volFields 包括常见的 volScalarField 和 volVectorField,是体积场量。无论是 volScalarField 还是 volVectorField 其实都是 GeometricField 的模板的不同情况。所以, volFields 只是一种模板类特化分组的称呼,而不是真正的类。
2.4. surfaceFields
同样的,面场量 surfaceFields 包括常见的 surfaceScalarField 和 surfaceVectorField 。
终端输入命令,查阅源文件
代码 surfaceFieldsFwd.H 中有类型定义如下
可见,surfaceFields 也是 GeometricField 的模板的不同情况。
Tip
surfaceFields 的 surface 都可以写完整,为什么 volFields 的 volume 要简写成 vol 呢?也许是历史代码的原因吧。。。
2.5. GeometricField
基于上文的讨论,我们查阅 GeometricField.H 代码
终端输入命令,查阅源文件
摘取类的主要结构和几个常用构造函数如下
上述构造函数,对应实际的场的构造,分别举例如下
这三个例子对应了最常见的场的构造函数,其他构造函数以及更深入的代码层面的解析在以后会陆续介绍,无需担心。读者也可以尝试自行多阅读几个。
3. 场的时间推进
我们以压力场为例,结合场的创建,讨论一下场的时间推进计算。
3.1. 单时间步计算
主源码 ofsp_17_field.C 内容如下
Tip
注意到主源码中的场的覆写是不区分初始时间步和后续时间步的,而且 foamCleanTutorials 命令不能恢复初始时间步文件夹内的场文件的内容。所以,为了避免初始条件被覆盖,强烈推荐备份初始条件。一旦初始场被覆盖,可以随时复原。
3.1.1. 脚本
脚本 caserun 修改为
脚本 caseclean 修改为
可以看到修改后的脚本更加通用。后续如非特别说明,可以直接拷贝使用此脚本。
3.1.2. 编译运行
终端输入命令,编译运行项目
终端输出如下
查看 debug_case/ 文件夹下,多了 0.005/ 文件夹,其中的 0.005/p 文件中写入了计算的场。最后的输出就是最新时间步的场的值。
3.2. 多时间步计算
如何在多个时间步上推进计算呢?
主源码修改如下
Tip
关于写成 ++runTime 而不是 runTime++ 的讨论
- 原则上来说,前置递增 ++a 比 后置递增 a++ 更高效
- 前置递增 ++a 直接递增并返回自身,避免潜在拷贝
- 后置递增则需要创建临时副本再增加并返回临时副本
- 对于内置类型(int, float, 指针等)现代编译器一般会优化掉差异
- 对于复杂类型(类、迭代器)前置更高效
编译运行项目
终端输出如下
观察 debug_case/ 文件夹下多了三个时间步的文件夹,现在的测试算例文件结构如下
查看各个时间步的压力场值,可以知道终端最后输出的值为最新时间步的计算值。
3.3. 字典控制计算
即使是多时间步计算,我们也是直接修改主源码的计算时间步个数,每次修改都要重新编译整个应用。如果是大型应用,重新编译会相当麻烦。
在实际工作中,我们希望在应用编译完成后,也可以通过外部文件去控制计算,也就是使用 OpenFOAM 的字典文件 controlDict 控制计算。
主源码修改为
编译运行项目
终端输出如下
测试算例 debug_case/ 文件多了几个时间步文件夹,分别是 0.1, 0.2, 0.3, 0.4, 0.5,写入的时间步由 system/controlDict 控制。
字典 controlDict 的部分参数如下(每
0.005*20 = 0.1 写入一次)这些参数都可以随时在字典中修改测试,无需重新编译项目。
4. 小结
本文介绍了 OpenFOAM 中的“场”。从代码和项目练习中,读者可以理解场是如何参与到计算项目中的。
本文完成讨论
理解场的代码结构
理解场的计算参与
编译运行 field 项目
支持我们
Tip
希望这里的分享可以对坚持、热爱又勇敢的您有所帮助。
如果这里的分享对您有帮助,您的评论或赞助将对本系列以及后续其他系列的更新、勘误、迭代和完善都有很大的意义,这些行动也会为后来的新同学的学习有很大的助益。
赞助打赏时的信息和留言将用于展示和感谢。

Copyright @ 2026 Aerosand
- 课程(文本、图片等):CC BY-NC-SA 4.0
- OpenFOAM 开发代码 :GPL v3
- 其他代码:MIT License
Loading...